﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

using DashFire;
using UnityEngine;
using UnityEditor;

public class ResVersionGenerator
{
  public static bool BuildResVersionFiles(bool isReGen = false)
  {
    Dictionary<string, ResBuildData> container = ResBuildGenerator.GetContainer(isReGen);
    if (container == null || container.Count == 0) {
      ResBuildLog.Warn("ResVersionGenerator.BuildResVersionFiles ResBuildProvider is null or empty.");
      return false;
    }
    foreach (ResBuildData data in container.Values) {
      GenerateProperty(data);
    }
    if (!OutputResVersionFile(container)) {
      ResBuildLog.Warn("ResVersionGenerator.BuildResVersion OutputResVersionFile failed.");
      return false;
    }
    ResBuildLog.Info("ResVersionGenerator.BuildResVersionFiles Success!");
    return true;
  }
  public static bool BuildSingleResVersionFiles(bool isAppend = true)
  {
    Dictionary<string, ResBuildData> container = ResBuildGenerator.GetRawContainer();
    if (container == null || container.Count == 0) {
      ResBuildLog.Warn("ResVersionGenerator.BuildResVersionFiles ResBuildProvider is null or empty.");
      return false;
    }
    foreach (ResBuildData data in container.Values) {
      GenerateProperty(data);
    }
    if (!OutputResVersionFile(container, true)) {
      ResBuildLog.Warn("ResVersionGenerator.BuildResVersion OutputResVersionFile failed.");
      return false;
    }
    ResBuildLog.Info("ResVersionGenerator.BuildResVersionFiles Success!");
    return true;
  }
  #region ResVersion
  public static bool LoadResVersion()
  {
    string filePath = ResBuildHelper.GetFilePathAbs(ResBuildHelper.FormatResListFilePath());
    if (string.IsNullOrEmpty(filePath)) {
      ResBuildLog.Warn("ResVersionGenerator.LoadResVersion failed:");
      return false;
    }
    try {
      ClientResVersionProvider.Instance.Clear();
      byte[] buffer = File.ReadAllBytes(filePath);
      bool ret = ClientResVersionProvider.Instance.CollectDataFromDBC(buffer);
      if (!ret) {
        ResBuildLog.Warn("ResVersionGenerator.LoadResVersion CollectDataFromDBC failed! filePath:" + filePath);
        return false;
      }
    } catch (System.Exception ex) {
      ResBuildLog.Warn("ResVersionGenerator.LoadResVersion failed! ex:" + ex);
      return false;
    }
    ResBuildLog.Info("ResVersionGenerator.LoadResVersion Success");
    return true;
  }
  private static bool OutputResVersionFile(Dictionary<string, ResBuildData> container, bool isAppend = false)
  {
    if (isAppend) {
      if (!LoadResVersion()) {
        ResBuildLog.Warn("ResVersionGenerator.OutputResVersionFile LoadResVersion failed!");
      }
      foreach (ResBuildData config in container.Values) {
        if (config != null && config.m_IsNeedBuild) {
          ResVersionData data = new ResVersionData();
          data.m_AssetBundleName = config.m_TargetName;
          data.m_AssetName = config.m_ResourcesName;
          data.m_AssetShortName = config.m_ResourcesShortName;
          data.m_MD5 = config.m_MD5;
          data.m_Size = config.m_Size;
          data.m_Version = ResBuildConfig.Version;
          ClientResVersionProvider.Instance.AddData(data);
        }
      }
      string filePath = ResBuildHelper.FormatResListFilePath();
      string fileContent = ResBuildConfig.ResVersionHeader + "\n";
      foreach (ClientResVersionData data in ClientResVersionProvider.Instance.GetArray().Values) {
        if (data != null) {
          string dataStr = string.Format(ResBuildConfig.ResVersionFormat + "\n",
            data.m_AssetBundleName, data.m_AssetName, data.m_AssetShortName, data.m_MD5, data.m_Size, ResBuildConfig.Version);
          fileContent += dataStr;
        }
      }
      try {
        if (!ResBuildHelper.CheckFilePath(filePath)) {
          ResBuildLog.Warn("ResVersionGenerator.OutputResVersionFile file not exist.");
          return false;
        }
        File.WriteAllText(filePath, fileContent, Encoding.UTF8);
      } catch (System.Exception ex) {
        ResBuildLog.Warn("ResVersionGenerator.OutputResVersionFile Save ClientResVersion failed!" + ex);
      }
    } else {
      string filePath = ResBuildHelper.FormatResListFilePath();
      string fileContent = ResBuildConfig.ResVersionHeader + "\n";
      foreach (ResBuildData config in container.Values) {
        if (config != null && config.m_IsNeedBuild) {
          string abInfo = string.Format(ResBuildConfig.ResVersionFormat + "\n",
            config.m_TargetName,
            config.m_ResourcesName,
            config.m_ResourcesShortName,
            config.m_MD5,
            config.m_Size,
            ResBuildConfig.Version
            );
          fileContent += abInfo;
        }
      }
      try {
        if (!ResBuildHelper.CheckFilePath(filePath)) {
          ResBuildLog.Warn("ResVersionGenerator.OutputResVersionFile file not exist.");
          return false;
        }
        File.WriteAllText(filePath, fileContent, Encoding.UTF8);
      } catch (System.Exception ex) {
        ResBuildLog.Warn("ResVersionGenerator.OutputResVersionFile failed!" + ex);
        return false;
      }
      AssetDatabase.Refresh();
    }
    ResBuildLog.Info("ResVersionGenerator.OutputResVersionFile Success");
    return true;
  }
  #endregion
  private static bool GenerateProperty(ResBuildData config)
  {
    string pathName = ResBuildHelper.FormatResPathFromConfig(config);
    string filePath = ResBuildHelper.GetFilePathAbs(pathName);
    if (File.Exists(filePath)) {
      config.m_MD5 = ResBuildHelper.GetFileMd5(filePath);
      config.m_Size = ResBuildHelper.GetFileSize(filePath);
    } else {
      ResBuildLog.Warn("ResVersionGenerator.GenerateProperty file not exist.filePath:" + filePath);
      config.m_MD5 = string.Empty;
      config.m_Size = 0;
    }
    return true;
  }
}
